<?php

namespace App\Exceptions;

use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * The list of the inputs that are never flashed to the session on validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     */
    public function register(): void
    {
        $this->reportable(function (Throwable $e) {
            //
        });

        if (Str::startsWith(request()->getRequestUri(), '/api')) {
            request()->headers->set('Accept', 'application/json');
        }
    }

    protected function unauthenticated($request, AuthenticationException $exception)
    {
        return $this->shouldReturnJson($request, $exception)
        ? response()->json(['status' => 401, 'success' => false, 'error' => ['code' => 'Unauthenticated', 'message' => '身份认证未通过']])
        : redirect()->guest($exception->redirectTo() ?? route('login'));
    }

    protected function invalidJson($request, ValidationException $exception)
    {
        return new JsonResponse(
            [
                'status' => 422,
                'success' => false,
                'error' => ['code' => 'validation_exception', 'message' => $exception->getMessage(), 'errors' => $exception->errors()],
            ],
            200,
            [],
            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
        );
    }

    protected function prepareJsonResponse($request, Throwable $e)
    {
        if ($e instanceof AppException) {
            $error = $e->getError();
        } else {
            $error = array_merge(['code' => 'server_error'], $this->convertExceptionToArray($e));
        }

        return new JsonResponse(
            [
                'status' => $this->isHttpException($e) ? $e->getStatusCode() : 422,
                'success' => false,
                'error' => $error,
            ],
            200,
            $this->isHttpException($e) ? $e->getHeaders() : [],
            JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES
        );
    }
}
